import clr
clr.AddReferenceByPartialName('System.Xml')
import System.Xml, System.Environment, System.Text
from System.Text.RegularExpressions import Regex

from System.Net import HttpWebRequest

def doQuery(host,account):
  proto = 'http' # or https if required
  path = 'Exchange/%s/Calendar' % account
  url = '%s://%s/%s' % ( proto, host, path )

  query = """<?xml version='1.0' ?><a:searchrequest xmlns:a='DAV:'><a:sql>SELECT "urn:schemas:httpmail:subject", "urn:schemas:calendar:dtstart", "urn:schemas:calendar:dtend","urn:schemas:calendar:location", "urn:schemas:calendar:dtend", "urn:schemas:calendar:rrule", "urn:schemas:calendar:uid" FROM scope('shallow traversal of "%s://%s/Exchange/%s/Calendar"') WHERE "DAV:ishidden"=False AND "DAV:isfolder"=False</a:sql></a:searchrequest>\r\n""" % ( proto, host, account)

  bytes = System.Text.Encoding.UTF8.GetBytes(query)

  length = bytes.Length

  request = HttpWebRequest.Create(url)

  request.Method = "SEARCH"

  request.ContentType = 'text/xml'
  request.ContentLength = length
  request.Headers.Add('Depth', '1')

  request.UseDefaultCredentials = True

  body = request.GetRequestStream()
  body.Write(bytes,0,bytes.Length)
  body.Close()
  
  response = request.GetResponse()
  xmldoc = System.Xml.XmlDocument()
  xmldoc.Load(response.GetResponseStream())

  nsmgr = System.Xml.XmlNamespaceManager(xmldoc.NameTable)
  nsmgr.AddNamespace( 'a', 'DAV:')
  nsmgr.AddNamespace( 'b', 'urn:schemas:httpmail:')
  nsmgr.AddNamespace( 'c', 'urn:schemas:calendar:')

  events = xmldoc.SelectNodes("//a:response", nsmgr)

  return (events,nsmgr)

def fixdt(dt):
  dt = Regex.Replace(dt,'-','')
  dt = Regex.Replace(dt,':','')
  dt = Regex.Replace(dt,'\.\d{3,3}Z','Z')
  return dt

def makeICS(events,nsmgr):
  events_ics = []
  for event in events:
    event_ics = "BEGIN:VEVENT\n"
    try:
      subject  = event.SelectSingleNode('.//b:subject',  nsmgr).InnerXml
      event_ics += 'SUMMARY:%s\n' % subject
    except: pass
    try:
      dtstart  = event.SelectSingleNode('.//c:dtstart',  nsmgr).InnerXml
      event_ics += 'DTSTART:%s\n' % fixdt(dtstart)
    except: pass
    try:
      dtend    = event.SelectSingleNode('.//c:dtend',    nsmgr).InnerXml
      event_ics += 'DTEND:%s\n' % fixdt(dtend)
    except: pass
    try:
      location = event.SelectSingleNode('.//c:location', nsmgr).InnerXml
      event_ics += 'LOCATION:%s\n' % location
    except: pass
    try:
      uid = event.SelectSingleNode('.//c:uid', nsmgr).InnerXml
      event_ics += 'UID:%s\n' % uid
    except: pass
    try:
      rrule = event.SelectSingleNode('.//c:rrule', nsmgr).FirstChild.InnerXml
      rrule = Regex.Replace(rrule,' ','')
      event_ics += 'RRULE:%s\n' % rrule
    except: pass
    event_ics += "END:VEVENT\n"
    events_ics.append(event_ics)
  return """BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//Jon Udell//Exchange To ICS//
%s
END:VCALENDAR""" % ''.join(events_ics)[:-1]

if __name__=="__main__": 
  try:
    args = System.Environment.GetCommandLineArgs()
    host = args[2]
    account = args[3]
    (events,nsmgr) = doQuery(host,account)
    print makeICS(events,nsmgr)
  except IndexError:
    print "ipy exchange2ical.py host account"
